package main

import (
	"fmt"
	"sync"
)

func main() {
	var wg sync.WaitGroup

	wg.Add(3)

	/**
	// 正确
	go handlerTask1(&wg)

	// 错误
	go handlerTask1(wg)

	执行子任务时，使用的 sync.WaitGroup 一定要是 wg 的引用类型！
	*/
	//超出任务数后，因为是并发，里面肯定会有一个任务不会执行，最好要注意一下任务调度的数量
	//go handlerTask1(&wg)
	go handlerTask1(&wg)
	go handlerTask2(&wg)
	go handlerTask3(&wg)

	//注意 wg.Add() 一定要在 wg.Wait() 执行前执行！
	wg.Wait()

	fmt.Println("全部任务执行完毕.")
}

func handlerTask1(wg *sync.WaitGroup) {
	//注意不要将 wg.Add() 放在 go handlerTask1(&wg) 中！
	//wg.Add(1) //错误的

	//注意 wg.Add() 和 wg.Done() 的计数器保持一致！其实 wg.Done() 就是执行的 wg.Add(-1) 。
	defer wg.Done()
	fmt.Println("执行任务 1")
}

func handlerTask2(wg *sync.WaitGroup) {
	defer wg.Done()
	fmt.Println("执行任务 2")
}

func handlerTask3(wg *sync.WaitGroup) {
	defer wg.Done()
	fmt.Println("执行任务 3")
}
